/***************************************************************************
 *   Copyright (C) 2008 by Dmitry Malakhov                                 *
 *   abr_mail@mail.ru                                                      *
 *                                                                         *
 *   This file is part of game Fifteens                                    *
 *                                                                         *
 *   Fifteens is free software; you can redistribute it and/or modify      *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   Fifteens is distributed in the hope that it will be useful,           *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

/*data.c*/

#if HAVE_CONFIG_H
#include <config.h>
#endif

#include <math.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>

#include "crypt.h"
#include "data.h"
#include "license.h"
#include "picdata.h"
#include <libintl.h>

#define _(String) gettext (String)

typedef struct
{
	int el;
	int move_b, direct;
	float move_a, arg, arg2;
} t_work_to_do;

t_work_to_do *work_to_do;

pthread_t mix_thread, solve_thread;

GtkWidget 	*menu_item_1_1_1,
			*menu_item_1_1_2,
			*menu_item_1_1_3,
			*menu_item_1_2,
			*menu_item_1_3,
			*menu_item_2_1,
			*menu_item_2_2,
			*buttons[15],
			*layout;

const int 	default_button_size = 111,
			source_pos[15][2] = {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {0, 1}, {1, 1}, {2, 1}, {3, 1}, {0, 2}, {1, 2}, {2, 2}, {3, 2}, {0, 3}, {1, 3}, {2, 3}};

int			button_pos[15][2],
			hole_pos[2] = {3, 3},
			button_coords[15][2],
			*console,
			console_p,
			*history,
			history_p,
			work_to_do_p,
			last_d,
			direct;

const float step_move_a = 2.56,
			step_arg_1 = 0.053,
			step_arg_2 = 0.04;

gboolean 	is_playing = FALSE,
			blocked_buttons[15] = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
			without_history = FALSE,
			called,
			dont_unblock = FALSE;

FILE 		*file;

void init_values()
{
	int i, j;
	console_p = -1;
	console = (int*)malloc(0 * sizeof(int));
	history_p = -1;
	history = (int*)malloc(0 * sizeof(int));
	work_to_do = (t_work_to_do*)malloc(0 * (3 * sizeof(int) + 3 * sizeof(float)));
	work_to_do_p = -1;

	for (i = 0; i <= 14; i++)
		for (j = 0; j <= 1; j++)
			button_pos[i][j] = source_pos[i][j];
}

void make_menu(GtkWidget *container)
{
	GtkWidget *menu_bar = gtk_menu_bar_new();
	gtk_box_pack_start(GTK_BOX(container), menu_bar, FALSE, FALSE, 2);
	gtk_widget_show(menu_bar);

	GtkWidget *menu_item_1 = gtk_menu_item_new_with_label(_("Game"));
	GtkWidget *menu_item_2 = gtk_menu_item_new_with_label(_("Solving"));
	GtkWidget *menu_item_3 = gtk_menu_item_new_with_label(_("About"));

	g_signal_connect_swapped(G_OBJECT(menu_item_3), "activate", G_CALLBACK(menuitem_3_response), NULL);

	gtk_widget_show(menu_item_1);
	gtk_widget_show(menu_item_2);
	gtk_widget_show(menu_item_3);

	gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), menu_item_1);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), menu_item_2);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), menu_item_3);

	GtkWidget *menu_1 = gtk_menu_new();

	GtkWidget *menu_item_1_1 = gtk_menu_item_new_with_label(_("Mix"));
	GtkWidget *menu_separator_1_1 = gtk_separator_menu_item_new();
	menu_item_1_2 = gtk_menu_item_new_with_label(_("Save"));
	menu_item_1_3 = gtk_menu_item_new_with_label(_("Open"));
	GtkWidget *menu_separator_1_2 = gtk_separator_menu_item_new();
	GtkWidget *menu_item_1_4 = gtk_menu_item_new_with_label(_("Exit"));

	g_signal_connect_swapped(G_OBJECT(menu_item_1_2), "activate", G_CALLBACK(menuitem_1_2_response), NULL);
	g_signal_connect_swapped(G_OBJECT(menu_item_1_3), "activate", G_CALLBACK(menuitem_1_3_response), NULL);
	g_signal_connect_swapped(G_OBJECT(menu_item_1_4), "activate", G_CALLBACK(gtk_widget_destroy), G_OBJECT(window));

	gtk_menu_shell_append(GTK_MENU_SHELL(menu_1), menu_item_1_1);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_1), menu_separator_1_1);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_1), menu_item_1_2);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_1), menu_item_1_3);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_1), menu_separator_1_2);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_1), menu_item_1_4);

	gtk_widget_show(menu_item_1_1);
	gtk_widget_show(menu_separator_1_1);
	gtk_widget_show(menu_item_1_2);
	gtk_widget_show(menu_item_1_3);
	gtk_widget_show(menu_separator_1_2);
	gtk_widget_show(menu_item_1_4);

	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item_1), menu_1);

	GtkWidget *menu_1_1 = gtk_menu_new();

	menu_item_1_1_1 = gtk_menu_item_new_with_label(_("Easy"));
	menu_item_1_1_2 = gtk_menu_item_new_with_label(_("Middle"));
	menu_item_1_1_3 = gtk_menu_item_new_with_label(_("Hard"));

	g_signal_connect_swapped(G_OBJECT(menu_item_1_1_1), "activate", G_CALLBACK(menuitem_1_1_response), (int *) 1);
	g_signal_connect_swapped(G_OBJECT(menu_item_1_1_2), "activate", G_CALLBACK(menuitem_1_1_response), (int *) 2);
	g_signal_connect_swapped(G_OBJECT(menu_item_1_1_3), "activate", G_CALLBACK(menuitem_1_1_response), (int *) 3);

	gtk_menu_shell_append(GTK_MENU_SHELL(menu_1_1), menu_item_1_1_1);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_1_1), menu_item_1_1_2);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_1_1), menu_item_1_1_3);

	gtk_widget_show(menu_item_1_1_1);
	gtk_widget_show(menu_item_1_1_2);
	gtk_widget_show(menu_item_1_1_3);

	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item_1_1), menu_1_1);

	GtkWidget *menu_2 = gtk_menu_new();

	menu_item_2_1 = gtk_menu_item_new_with_label(_("Step"));
	menu_item_2_2 = gtk_menu_item_new_with_label(_("Solve"));

	g_signal_connect_swapped(G_OBJECT(menu_item_2_1), "activate", G_CALLBACK(menuitem_2_1_response), NULL);
	g_signal_connect_swapped(G_OBJECT(menu_item_2_2), "activate", G_CALLBACK(menuitem_2_2_response), NULL);

	gtk_menu_shell_append(GTK_MENU_SHELL(menu_2), menu_item_2_1);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu_2), menu_item_2_2);

	gtk_widget_show(menu_item_2_1);
	gtk_widget_show(menu_item_2_2);

	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item_2), menu_2);

	gtk_widget_set_sensitive(menu_item_2_1, FALSE);
	gtk_widget_set_sensitive(menu_item_2_2, FALSE);
}

void menuitem_1_1_response(int k)
{
	int steps = rand() % (k * 9) + k * 15;
	pthread_create(&mix_thread, NULL, mix, (void *)steps);
}

void menuitem_1_2_response(int k)
{
	int i;
	char buf[1];
	t_ciph_string c_data, info;
	info.str = (char*)malloc((34 + history_p) * sizeof(char));
	info.length = 34 + history_p;

	file = fopen("save", "w");
	memcpy(info.str, &hole_pos[0], 1);
	memcpy(info.str + 1, &hole_pos[1], 1);
	for (i = 0; i <= 14; i++)
	{
		memcpy(info.str + 2 + i * 2, &button_pos[i][0], 1);
		memcpy(info.str + 3 + i * 2, &button_pos[i][1], 1);
	}
	for (i = 0; i <= history_p; i++)
		memcpy(info.str + 32 + i, &history[i], 1);
	if (is_playing)
		buf[0] = 5;
	else
		buf[0] = 6;
	memcpy(info.str + 33 + history_p, &buf, 1);

	c_data = tciph(info);

	fwrite(c_data.str, 1, c_data.length, file);

	fclose(file);
}

void menuitem_1_3_response(int k)
{
	int i, c_data_len;
	char buf, buf_data[64];
	t_ciph_string c_data, info;
	file = fopen("save", "r");
	if (file != NULL)
	{
		c_data.str = (char*)malloc(0 * sizeof(char));
		c_data.length = 0;

		do
		{
			i = fread(buf_data, 1, 64, file);
			if (i > 0)
			{
				c_data.length += i;
				c_data.str = (char*)realloc(c_data.str, c_data.length * sizeof(char));
				memcpy(c_data.str + c_data.length - i, buf_data, i);
			}
		} while (i != 0);

		info = tdeciph(c_data);

		if (info.length > 32)
		{
			hole_pos[0] = (int)info.str[0];
			hole_pos[1] = (int)info.str[1];
			for (i = 0; i <= 14; i++)
			{
				button_pos[i][0] = (int)info.str[2 + i * 2];
				button_pos[i][1] = (int)info.str[3 + i * 2];
				button_coords[i][0] = button_pos[i][0] * default_button_size;
				button_coords[i][1] = button_pos[i][1] * default_button_size;
				gtk_layout_move(GTK_LAYOUT(layout), buttons[i], button_coords[i][0], button_coords[i][1]);
			}		
			clear_history();
			for (i = 32; i < info.length; i++)
				if ((int)info.str[i] == 5)
					is_playing = TRUE;
				else if ((int)info.str[i] == 6)
					is_playing = FALSE;
				else
					array_add(&history, &history_p, (int)info.str[i]);
		}
		fclose(file);
	}
	gtk_widget_set_sensitive(menu_item_1_1_1, !is_playing);
	gtk_widget_set_sensitive(menu_item_1_1_2, !is_playing);
	gtk_widget_set_sensitive(menu_item_1_1_3, !is_playing);

	if (history_p >= 0)
	{
		gtk_widget_set_sensitive(menu_item_2_1, TRUE);
		gtk_widget_set_sensitive(menu_item_2_2, TRUE);
	}
}

void menuitem_2_1_response()
{
	int h_el, i, h_direction = history[history_p];

	if (history[history_p] == 1)
		h_el = find_by_coords(hole_pos[0], hole_pos[1] - 1);
	else if (history[history_p] == 2)
		h_el = find_by_coords(hole_pos[0] + 1, hole_pos[1]);
	else if (history[history_p] == 3)
		h_el = find_by_coords(hole_pos[0], hole_pos[1] + 1);
	else if (history[history_p] == 4)
		h_el = find_by_coords(hole_pos[0] - 1, hole_pos[1]);

	without_history = TRUE;
	if (button_click(NULL, (gpointer) h_el))
	{
		shrink_array(&history, &history_p);
		if (history_p < 0)
		{
			gtk_widget_set_sensitive(menu_item_2_1, FALSE);
			gtk_widget_set_sensitive(menu_item_2_2, FALSE);
		}
	}
	without_history = FALSE;
}

void menuitem_2_2_response()
{
	pthread_create(&solve_thread, NULL, solve, NULL);
}

void menuitem_3_response()
{
	GtkWidget *window_about = gtk_about_dialog_new();

	const gchar *authors [] = {_("Idea: Gumerov Karen"), _("Code: Malakhov Dmitry"), NULL};
	gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(window_about), _("Fifteens"));
	gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(window_about), VERSION);
	gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(window_about), _("2010 (c) Malakhov Dmitry"));
	gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(window_about), "Game without breaks!"); 
	gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(window_about), license);
	gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(window_about), "http://code.google.com/p/fifteens");
	gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(window_about), authors);
	gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(window_about), NULL);
	
	gtk_dialog_run(GTK_DIALOG(window_about));
	gtk_widget_destroy(window_about);
}

void make_buttons(GtkWidget *container)
{
	GtkWidget *button, *image, *event_box;
	GdkPixbuf *pb;
	int i, j;

	layout = gtk_layout_new(NULL, NULL);

	for (i = 0; i <= 3; i++)
		for (j = 0; j <= 3; j++)
			if (i + j != 6)
			{
				pb = gdk_pixbuf_new_from_inline(-1, picdata[i * 4 + j], FALSE, NULL);
				image = gtk_image_new_from_pixbuf(pb);

				button = gtk_button_new();
				gtk_button_set_image(GTK_BUTTON(button), image);
				g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_click), (int *) (i * 4 + j));

				gtk_layout_put(GTK_LAYOUT(layout), button, j * default_button_size, i * default_button_size);
				button_coords[i * 4 + j][0] = j * default_button_size;
				button_coords[i * 4 + j][1] = i * default_button_size;

				buttons[i * 4 + j] = button;

				gtk_widget_show(button);
				gtk_widget_show(image);
			}
	gtk_box_pack_end(GTK_BOX(container), layout, TRUE, TRUE, 2);
	gtk_widget_show(layout);
}

gboolean button_click(GtkWidget *widget, gpointer data)
{
	if (!blocked_buttons[(int) data])
	{
		int init_move = check_move((int) data);
		if (init_move > 0)
		{
			blocked_buttons[(int) data] = TRUE;
			gtk_widget_set_sensitive(menu_item_2_1, FALSE);
			gtk_widget_set_sensitive(menu_item_2_2, FALSE);
			array_add(&console, &console_p, (int) data + (init_move - 1) * 15);

			if (!without_history) array_add(&history, &history_p, init_move);
			if (!dont_unblock) gtk_widget_set_sensitive(menu_item_2_1, TRUE);
			if (!dont_unblock) gtk_widget_set_sensitive(menu_item_2_2, TRUE);
			return TRUE;
		}
		else
			return FALSE;
	}
	else
		return FALSE;
}

int check_move(int index)
{
	if (button_pos[index][0] > 0 && hole_pos[0] == button_pos[index][0] - 1 && hole_pos[1] == button_pos[index][1])
	{
		button_pos[index][0] -= 1;
		hole_pos[0] += 1;
		return 4;
	}
	if (button_pos[index][0] < 3 && hole_pos[0] == button_pos[index][0] + 1 && hole_pos[1] == button_pos[index][1])
	{
		button_pos[index][0] += 1;
		hole_pos[0] -= 1;
		return 2;
	}
	if (button_pos[index][1] > 0 && hole_pos[0] == button_pos[index][0] && hole_pos[1] == button_pos[index][1] - 1)
	{
		button_pos[index][1] -= 1;
		hole_pos[1] += 1;
		return 1;
	}
	if (button_pos[index][1] < 3 && hole_pos[0] == button_pos[index][0] && hole_pos[1] == button_pos[index][1] + 1)
	{
		button_pos[index][1] += 1;
		hole_pos[1] -= 1;
		return 3;
	}
	return 0;
}

gboolean on_timeout(GtkWidget *widget)
{
	int i, j;
	gboolean res;
	for (i = 0; i <= console_p; i++)
	{
		expand_work_to_do();
		work_to_do[work_to_do_p].el = get_from_console(0);
		work_to_do[work_to_do_p].direct = get_from_console(1);
		if (work_to_do[work_to_do_p].direct & 1)
		{
			work_to_do[work_to_do_p].move_a = button_coords[get_from_console(0)][1];
			work_to_do[work_to_do_p].move_b = button_coords[get_from_console(0)][1];
		}
		else
		{
			work_to_do[work_to_do_p].move_a = button_coords[get_from_console(0)][0];
			work_to_do[work_to_do_p].move_b = button_coords[get_from_console(0)][0];
		}
		while (work_to_do[work_to_do_p].move_a >= default_button_size)
			work_to_do[work_to_do_p].move_a -= default_button_size;

		work_to_do[work_to_do_p].arg = 0;
		work_to_do[work_to_do_p].arg2 = step_move_a;

		for (j = 1; j <= console_p; j++)
			console[j - 1] = console[j];
		shrink_array(&console, &console_p);
	}

	if (work_to_do_p > -1)
	{
		for (i = 0; i <= work_to_do_p; i++)
		{
			if (work_to_do[i].direct == 2 || work_to_do[i].direct == 3)
			{
				if (work_to_do[i].move_a <= default_button_size/2)
					work_to_do[i].move_a += step_move_a;
				else
				{
					work_to_do[i].arg += step_arg_1;
					work_to_do[i].arg2 += step_arg_2;
					work_to_do[i].move_a += work_to_do[i].arg2 * cos(work_to_do[i].arg);
				}
				if (work_to_do[i].direct == 2)
				{
					gtk_layout_move(GTK_LAYOUT(layout), buttons[work_to_do[i].el], (int)(work_to_do[i].move_a) + work_to_do[i].move_b, button_coords[work_to_do[i].el][1]);
					button_coords[work_to_do[i].el][0] = (int)(work_to_do[i].move_a) + work_to_do[i].move_b;
				}
				else if (work_to_do[i].direct == 3)
				{
					gtk_layout_move(GTK_LAYOUT(layout), buttons[work_to_do[i].el], button_coords[work_to_do[i].el][0], (int)(work_to_do[i].move_a) + work_to_do[i].move_b);
					button_coords[work_to_do[i].el][1] = (int)(work_to_do[i].move_a) + work_to_do[i].move_b;
				}
			}
			else if (work_to_do[i].direct == 1 || work_to_do[i].direct == 4)
			{
				if (work_to_do[i].move_a >= -default_button_size/2)
					work_to_do[i].move_a -= step_move_a;
				else
				{
					work_to_do[i].arg += step_arg_1;
					work_to_do[i].arg2 += step_arg_2;
					work_to_do[i].move_a -= work_to_do[i].arg2 * cos(work_to_do[i].arg);
				}
				if (work_to_do[i].direct == 4)
				{
					gtk_layout_move(GTK_LAYOUT(layout), buttons[work_to_do[i].el], (int)(work_to_do[i].move_a) + work_to_do[i].move_b, button_coords[work_to_do[i].el][1]);
					button_coords[work_to_do[i].el][0] = (int)(work_to_do[i].move_a) + work_to_do[i].move_b;
				}
				else
				{
					gtk_layout_move(GTK_LAYOUT(layout), buttons[work_to_do[i].el], button_coords[work_to_do[i].el][0], (int)(work_to_do[i].move_a) + work_to_do[i].move_b);
					button_coords[work_to_do[i].el][1] = (int)(work_to_do[i].move_a) + work_to_do[i].move_b;
				}
			}
			if (is_playing && game_finished())
				buttons_lock(TRUE);
			if (work_to_do[i].move_a >= default_button_size || work_to_do[i].move_a <= -default_button_size)
			{
				if (is_playing && game_finished() && work_to_do_p == 0)
				{
					GtkWidget* dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, _("Done!"), NULL);
					gtk_window_set_title(GTK_WINDOW(dialog), _("Victory!"));
					gtk_dialog_run(GTK_DIALOG(dialog));
					gtk_widget_destroy(dialog);
					clear_history();

					gtk_widget_set_sensitive(menu_item_2_1, FALSE);
					gtk_widget_set_sensitive(menu_item_2_2, FALSE);
					gtk_widget_set_sensitive(menu_item_1_1_1, TRUE);
					gtk_widget_set_sensitive(menu_item_1_1_2, TRUE);
					gtk_widget_set_sensitive(menu_item_1_1_3, TRUE);

					is_playing = FALSE;
					buttons_lock(FALSE);
				}
				blocked_buttons[work_to_do[i].el] = FALSE;
				for (j = i; j <= work_to_do_p; j++)
					if (j < work_to_do_p)
						work_to_do[j] = work_to_do[j + 1];
				shrink_work_to_do();
			}
		}
	}
	return TRUE;
}

void array_add(int *arr[], int *arr_p, int d)
{
	*arr = (int*)realloc(*arr, (++(*arr_p) + 1) * sizeof(int));
	(*arr)[*arr_p] = d;
}

void shrink_array(int *arr[], int *arr_p)
{
	*arr = (int*)realloc(*arr, (--(*arr_p) + 1) * sizeof(int));
}

void expand_work_to_do()
{
	work_to_do = (t_work_to_do*)realloc(work_to_do, (++work_to_do_p + 1)*(3 * sizeof(int) + 3 * sizeof(float)));
}

void shrink_work_to_do()
{
	work_to_do = (t_work_to_do*)realloc(work_to_do, (--work_to_do_p + 1)*(3 * sizeof(int) + 3 * sizeof(float)));
}

void clear_history()
{
	history = (int*)realloc(history, 0*sizeof(int));
	history_p = -1;
}

int get_from_console(int k)
{
	int res[2];
	res[0] = console[0];
	for (res[1] = 0; res[0] >= 15; res[1]++)
		res[0] -= 15;
	res[1]++;
	return res[k];
}

gboolean game_finished()
{
	int i, j;
	for (i = 0; i <= 14; i++)
		for (j = 0; j <= 1; j++)
			if (button_pos[i][j] != source_pos[i][j])
				return FALSE;
	return TRUE;
}

void buttons_lock(gboolean state)
{
	int i;
	for (i = 0; i <= 14; i++)
		gtk_widget_set_sensitive(buttons[i], !state);
}

int find_by_coords(int x, int y)
{
	int i;
	for (i = 0; i <= 14; i++)
		if (button_pos[i][0] == x && button_pos[i][1] == y)
			return i;
}

void * mix(void *steps)
{
	int i, rnd;
	array_add(&console, &console_p, 61);

	buttons_lock(TRUE);
	dont_unblock = TRUE;

	gtk_widget_set_sensitive(menu_item_1_2, FALSE);
	gtk_widget_set_sensitive(menu_item_1_3, FALSE);
	gtk_widget_set_sensitive(menu_item_2_1, FALSE);
	gtk_widget_set_sensitive(menu_item_2_2, FALSE);
	gtk_widget_set_sensitive(menu_item_1_1_1, FALSE);
	gtk_widget_set_sensitive(menu_item_1_1_2, FALSE);
	gtk_widget_set_sensitive(menu_item_1_1_3, FALSE);

	last_d = 0;
	for (i = 1; i <= (int)steps; i++)
	{
		rnd = rand() % 200 - 100;
		if (last_d == 0)
		{
			if (rnd > 0)
				direct = 3;
			else
				direct = 2;
		}
		else
			if (rnd > 0)
			{
				if (rnd & 1)
				{
					if (last_d == 1)
					{
						if (hole_pos[0] > 0)
							direct = 2;
						else
							direct = 4;
					}
					else if (last_d == 2)
				{
						if (hole_pos[1] > 0)
							direct = 3;
						else
							direct = 1;
					}
					else if (last_d == 3)
					{
						if (hole_pos[0] < 3)
							direct = 4;
						else
							direct = 2;
				}
					else if (last_d == 4)
					{
						if (hole_pos[1] < 3)
							direct = 1;
						else
							direct = 3;
					}
				}
				else
				{
					if (last_d == 1)
					{
						if (hole_pos[0] < 3)
							direct = 4;
						else
							direct = 2;
				}
					else if (last_d == 2)
					{
						if (hole_pos[1] < 3)
							direct = 1;
						else
							direct = 3;
					}
					else if (last_d == 3)
					{
						if (hole_pos[0] > 0)
							direct = 2;
						else
							direct = 4;
					}
					else if (last_d == 4)
					{
						if (hole_pos[1] > 0)
							direct = 3;
						else
							direct = 1;
					}
				}
			}
			else
			{
				if (last_d == 1)
				{
					if (hole_pos[1] < 3)
						direct = 1;
					else
						if (hole_pos[0] > 0)
							direct = 2;
						else
							direct = 4;
				}
				else if (last_d == 2)
				{
				if (hole_pos[0] > 0)
						direct = 2;
					else
						if (hole_pos[1] > 0)
							direct = 3;
						else
							direct = 1;
				}
				else if (last_d == 3)
				{
					if (hole_pos[1] > 0)
						direct = 3;
					else
						if (hole_pos[0] < 3)
							direct = 4;
						else
							direct = 2;
				}
				else if (last_d == 4)
				{
					if (hole_pos[0] < 3)
						direct = 4;
					else
						if (hole_pos[1] < 3)
							direct = 1;
						else
							direct = 3;
				}
			}

		called = FALSE;

		if (direct == 1)
			called = button_click(NULL, (gpointer) find_by_coords(hole_pos[0], hole_pos[1] + 1));
		else if (direct == 2)
			called = button_click(NULL, (gpointer) find_by_coords(hole_pos[0] - 1, hole_pos[1]));
		else if (direct == 3)
			called = button_click(NULL, (gpointer) find_by_coords(hole_pos[0], hole_pos[1] - 1));
		else if (direct == 4)
			called = button_click(NULL, (gpointer) find_by_coords(hole_pos[0] + 1, hole_pos[1]));
		if (called) last_d = direct;
		else i--;
		usleep(500000);
	}

	array_add(&console, &console_p, 60);
	is_playing = TRUE;

	dont_unblock = FALSE;
	buttons_lock(FALSE);

	gtk_widget_set_sensitive(menu_item_1_2, TRUE);
	gtk_widget_set_sensitive(menu_item_1_3, TRUE);
	gtk_widget_set_sensitive(menu_item_2_1, TRUE);
	gtk_widget_set_sensitive(menu_item_2_2, TRUE);
}

void * solve(void *arg)
{
	int i;
	array_add(&console, &console_p, 61);

	buttons_lock(TRUE);
	dont_unblock = TRUE;

	gtk_widget_set_sensitive(menu_item_1_2, FALSE);
	gtk_widget_set_sensitive(menu_item_1_3, FALSE);
	gtk_widget_set_sensitive(menu_item_2_1, FALSE);
	gtk_widget_set_sensitive(menu_item_2_2, FALSE);
	gtk_widget_set_sensitive(menu_item_1_1_1, FALSE);
	gtk_widget_set_sensitive(menu_item_1_1_2, FALSE);
	gtk_widget_set_sensitive(menu_item_1_1_3, FALSE);

	called = FALSE;

	while (history_p > -1)
	{
		menuitem_2_1_response();
		usleep(500000);
	}
	is_playing = FALSE;

	dont_unblock = FALSE;
	buttons_lock(FALSE);

	gtk_widget_set_sensitive(menu_item_1_2, TRUE);
	gtk_widget_set_sensitive(menu_item_1_3, TRUE);
	gtk_widget_set_sensitive(menu_item_1_1_1, TRUE);
	gtk_widget_set_sensitive(menu_item_1_1_2, TRUE);
	gtk_widget_set_sensitive(menu_item_1_1_3, TRUE);
}
